﻿
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Threading;
using System.Configuration;
using MergerProject;
using System.Xml.Serialization;
using System.Xml;
using MergeToolSample;
using MergeToolSample2013.Properties;

namespace AktarimMaddeleri
{
    public partial class Form1 : Form
    {

        bool loadCompleted = false;
        public IMerger merger = null;



        public Form1()
        {
            InitializeComponent();

        }


        public void FillGrid()
        {
            if (merger.mergeTable != null)
              CountLabel.Invoke(new Action(()=>  CountLabel.Text = merger.mergeTable.Rows.Count.ToString()));

            DataSet dataSet = new DataSet("myDataset");
            dataSet.Tables.Add(merger.mergeTable);
            dataSet.Tables.Add(merger.changeSetDetailsTable);
            DataRelation relation = dataSet.Relations.Add("myrelation", merger.mergeTable.Columns[1],
                                             merger.changeSetDetailsTable.Columns[0], true);

            dataGridView1.AllowUserToAddRows = false;

            dataGridView1.Invoke(new Action(() => dataGridView1.Columns.Clear()));
            dataGridView1.AutoGenerateColumns = true;
            dataGridView1.Invoke(new Action(() => dataGridView1.DataSource = dataSet.Tables[0]));

            // Add a button column. 
            DataGridViewButtonColumn buttonColumn =
                new DataGridViewButtonColumn();
            buttonColumn.HeaderText = "";
            buttonColumn.Name = "MergeButton";
            dataGridView1.Invoke(new Action(() => dataGridView1.Columns.Add(buttonColumn)));

            DataGridViewButtonColumn buttonColumn2 =
              new DataGridViewButtonColumn();
            buttonColumn2.HeaderText = "Detail";
            buttonColumn2.Name = "Detail";
            dataGridView1.Invoke(new Action(() => dataGridView1.Columns.Add(buttonColumn2)));


            dataGridView1.Invoke(new Action(() => dataGridView1.Columns[0].Width = 75));
            dataGridView1.Invoke(new Action(() => dataGridView1.Columns[1].Width = 100));
            dataGridView1.Invoke(new Action(() => dataGridView1.Columns[2].Width = 150));



            for (int i = 0; i < merger.mergeTable.Rows.Count; i++)
            {

                DataGridViewButtonCell button = dataGridView1.Rows[i].Cells["MergeButton"] as DataGridViewButtonCell;
                button.Value = "Merge=>" + merger.mergeTable.Rows[i][1].ToString();
                DataGridViewButtonCell button2 = dataGridView1.Rows[i].Cells["Detail"] as DataGridViewButtonCell;
                button2.Value = "Detail";
                if (dataGridView1.Rows[i].Cells["Merged"].ToString() == "true" || dataGridView1.Rows[i].Cells["Merged"].ToString() == "True")
                {
                    dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Red;
                    button.ReadOnly = true;
                }

            }
            waitLabel.Invoke(new Action(() => waitLabel.Visible = false));
            dataGridView1.Invoke(new Action(() => dataGridView1.Refresh()));
            if (merger.mergeTable != null && merger.mergeTable.Rows.Count > 0)
                BulkMergeButton.Invoke(new Action(() => BulkMergeButton.Enabled = true));
            else
                BulkMergeButton.Invoke(new Action(() => BulkMergeButton.Enabled = false));

        }



        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

            if (dataGridView1.Columns[e.ColumnIndex].CellType == typeof(DataGridViewButtonCell) && dataGridView1.Columns[e.ColumnIndex].Name == "MergeButton")
            {
                PendingChangesListBox.Items.Clear();
                ConflictListBox.Items.Clear();
                workItemTextBox.Text = string.Empty;
                commentTextBox.Text = string.Empty;
                DataGridViewButtonCell buttonCell = dataGridView1.Rows[e.RowIndex].Cells["MergeButton"] as DataGridViewButtonCell;
                buttonCell.FlatStyle = FlatStyle.Standard;

                string workitemid = merger.mergeTable.Rows[e.RowIndex][0].ToString();
                string changesetid = merger.mergeTable.Rows[e.RowIndex][1].ToString();
                string desc = merger.mergeTable.Rows[e.RowIndex][2].ToString();
                bool merged = merger.MergeChangeSet(workitemid, changesetid, desc, false);
                if (merged)
                    ((DataTable)dataGridView1.DataSource).Rows[e.RowIndex]["Merged"] = "True";


            }
            if (dataGridView1.Columns[e.ColumnIndex].CellType == typeof(DataGridViewButtonCell) && dataGridView1.Columns[e.ColumnIndex].Name == "Detail")
            {
                string changesetID = merger.mergeTable.Rows[e.RowIndex][1].ToString();
                DataRow[] drow = merger.changeSetDetailsTable.Select("ChangeSetID=" + changesetID);
                DataTable dt = merger.GetMergeChangeSetDetailTable();
                for (int i = 0; i < drow.Length; i++)
                {
                    DataRow mrow = dt.NewRow();
                    mrow[0] = drow[i][0];
                    mrow[1] = drow[i][1];
                    mrow[2] = drow[i][2];
                    dt.Rows.Add(mrow);
                }
                Form2 frm2 = new Form2();
                frm2.dataSourceTable = dt;
                frm2.ShowDialog();



            }

        }

       private void Form1_Load(object sender, EventArgs e)
        {

            InitializeForm();
        }

        public void InitializeForm()
        {
            try
            {
                loadCompleted = false;
                Merger2013._loggerDelegate = new Merger2013.LoggerDelegate(log);
                Merger2013._pendingChangesDelegate = new Merger2013.PendingChangesDelegate(AddToPendingChanges);
                Merger2013._conflictsDelegate = new Merger2013.conflictsDelegate(AddToConflictBox);

                merger = new Merger2013();




                GetServersFromXML();
                string tfsUrl = string.Empty;
                string defaultProjectName = string.Empty;
                if (System.Configuration.ConfigurationSettings.AppSettings["TfsUrl"]!=null)
                tfsUrl = System.Configuration.ConfigurationSettings.AppSettings["TfsUrl"].ToString();
                if (System.Configuration.ConfigurationSettings.AppSettings["DefaultProjectName"]!= null)
                defaultProjectName = System.Configuration.ConfigurationSettings.AppSettings["DefaultProjectName"].ToString();
                merger.Initialize(tfsUrl, defaultProjectName);
                SaveProjectName();
                FillServersCombo();
                getAllUsers();
                getProjectDataTable();
                getBranchList(0);
                getUserWorkItemList();
                loadCompleted = true;
                PendingChangesListBox.Items.Clear();
                ConflictListBox.Items.Clear();
                workItemTextBox.Text = string.Empty;
                commentTextBox.Text = string.Empty;
            }
            catch (Exception ex)
            {

                loadCompleted = true;
                throw ex;

            }
        }

        public void FillServersCombo()
        {
            DataTable dt = merger.GetServers();
            serverListCombo.DataSource = dt;
            serverListCombo.DisplayMember = "Url";
            serverListCombo.ValueMember = "Url";
            serverListCombo.SelectedValue = merger.tfsUrl;

        }

        public void getAllUsers()
        {
            DataTable userTable = merger.getAllUsersTable();
            if (userTable != null && userTable.Rows.Count > 0)
            {
                userListComboBox.DataSource = userTable;
                userListComboBox.DisplayMember = "UserName";
                userListComboBox.ValueMember = "UserID";
                userListComboBox.Text = merger.getUserName();
                merger.selectedUser = userListComboBox.Text;
            }

        }

        public void getBranchList(int index)
        {
            DataTable sourceBranchTables = merger.getBranchListTable();
            SourceBranchListcomboBox.DataSource = sourceBranchTables;
            SourceBranchListcomboBox.DisplayMember = "Name";
            if (sourceBranchTables != null && sourceBranchTables.Rows.Count > 1)
            {
                DataTable destBranchTable = sourceBranchTables.DefaultView.ToTable();
                destBranchTable.Rows.RemoveAt(index);
                DestBranchListcomboBox.DataSource = destBranchTable;
                DestBranchListcomboBox.DisplayMember = "Name";
                merger.DetermineWorkSpaces(sourceBranchTables.Rows[index]["Name"].ToString(), destBranchTable.Rows[index]["Name"].ToString());
            }
            else
                DestBranchListcomboBox.DataSource = null;
        }

        public void setDestBranchList(int index)
        {
            DataTable sourceBranchTables = merger.branchTable;
            DataTable destBranchTable = sourceBranchTables.DefaultView.ToTable();
            destBranchTable.Rows.RemoveAt(index);
            DestBranchListcomboBox.DataSource = destBranchTable;
            DestBranchListcomboBox.DisplayMember = "Name";
            merger.DetermineWorkSpaces(sourceBranchTables.Rows[index]["Name"].ToString(), destBranchTable.Rows[0]["Name"].ToString());
        }


        public void getProjectDataTable()
        {
            DataTable dt = merger.getProjectsDataTable();
            ProjectListcomboBox.DataSource = dt;
            ProjectListcomboBox.DisplayMember = "Name";
            ProjectListcomboBox.Text = merger.selectedProjectName;

        }

        public void getUserWorkItemList()
        {
            DataTable dt = merger.getUserWorkItemListTable();
            workItemListComboBox.DataSource = null;
            workItemListComboBox.DataSource = dt;
            workItemListComboBox.DisplayMember = "desc";
            workItemListComboBox.ValueMember = "wiid";

        }

        private void showWaitMessage()
        {

            this.Invoke(new Action(() => this.Refresh()));
            waitLabel.Invoke(new Action(() => waitLabel.Visible = true));



        }

        private void GetListButton_Click(object sender, EventArgs e)
        {
            PendingChangesListBox.Items.Clear();
            ConflictListBox.Items.Clear();
            workItemTextBox.Text = string.Empty;
            commentTextBox.Text = string.Empty;
            backgroundWorker2.RunWorkerAsync();
            backgroundWorker1.RunWorkerAsync();
        }

        public void getList()
        {
            try
            {
                BulkMergeButton.Invoke(new Action(() => BulkMergeButton.Enabled = false));
                GetListButton.Invoke(new Action(() => GetListButton.Enabled = false));
                string workItems = string.Empty;
                string workitemText = string.Empty;
                workItemListComboBox.Invoke(new Action(() => workitemText = workItemListComboBox.Text));
                workItems = workitemText;
                if (workitemText.Contains("=>"))
                    workItems = workitemText.Substring(0, workitemText.IndexOf("=>"));

                List<string> workItemsList = workItems.Split(new char[] { ',' }).ToList();
                merger.workItemIDs = workItemsList;
                merger.FillMergeTable();
                FillGrid();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " " + ex.StackTrace);
            }
            finally
            {
                GetListButton.Invoke(new Action(() => GetListButton.Enabled = true));
            }

        }

        public delegate void RefreshForm();
        public delegate void UpdateRichTextBox(string text);

        public void FormRefresh()
        {
            if (!merger.bulkmergeStarted)
            {
                BulkMergeButton.Invoke(new Action(() => BulkMergeButton.Text = "Toplu Merge Başlat"));

            }

        }

        public void UpdateRichTextBoxText(string text)
        {
            logTextBox.Invoke(new Action(() => UpdateRichTextBoxText2(text)));



        }

        public void UpdateRichTextBoxText2(string text)
        {
            logTextBox.Text += text;
            logTextBox.SelectionStart = logTextBox.Text.Length; //Set the current caret position at the end
            logTextBox.ScrollToCaret(); //Now scroll it automatically


        }



        public void StartBulkMerge()
        {
            try
            {
                merger.StartBulkMerge();
            }
            catch (Exception ex)
            {
                merger.bulkmergeStarted = false;
                MessageBox.Show(ex.Message);
                Thread.CurrentThread.Abort();
                throw ex;
            }



        }

        public void StartBulkMerge(List<string> mergelist )
        {
            try
            {
                merger.StartBulkMerge(mergelist);
            }
            catch (Exception ex)
            {
                merger.bulkmergeStarted = false;
                MessageBox.Show(ex.Message);
                Thread.CurrentThread.Abort();
                throw ex;
            }



        }

        private void BulkMergeButton_Click(object sender, EventArgs e)
        {
            PendingChangesListBox.Items.Clear();
            ConflictListBox.Items.Clear();
            workItemTextBox.Text = string.Empty;
            commentTextBox.Text = string.Empty;

            if (merger.mergeTable == null || merger.mergeTable.Rows.Count == 0)
            {
                MessageBox.Show("Lütfen öncelikle merge yapılacak branch'ları seçip, workItem'ın changesetlerini listeletiniz. Bunun için Branches listesinden Branch seçip, Workitems listesinden workitem seçip veya istediğiniz bir workitem'ın numarasını elle yazarak Listele butonuna basmanız yeterlidir.");
                return;
            }
            RefreshForm fr = new RefreshForm(FormRefresh);
            if (merger.bulkmergeStarted)
            {
                merger.bulkmergeStarted = false;
                fr.Invoke();
                return;
            }

            try
            {
                BulkMergeButton.Text = "Stop Process";
                merger.bulkmergeStarted = true;
                backgroundWorker3.RunWorkerAsync();


            }
            catch (Exception ex)
            {
                merger.bulkmergeStarted = false;
                MessageBox.Show(ex.Message);
                fr.Invoke();
                throw ex;
            }


        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            getList();
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            showWaitMessage();
        }



        private void ProjectListcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (loadCompleted)
            {
                loadCompleted = false;
                merger.selectedProjectName = ProjectListcomboBox.Text;
                getBranchList(0);
                getUserWorkItemList();
                SaveProjectName();
                dataGridView1.DataSource = null;
                BulkMergeButton.Enabled = false;
                selectedChangesButton.Enabled = false;
                loadCompleted = true;

            }

        }

        private void SourceBranchListcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (loadCompleted)
            {
                loadCompleted = false;
                int selectedIndex = SourceBranchListcomboBox.SelectedIndex;
                setDestBranchList(selectedIndex);
                dataGridView1.DataSource = null;
                BulkMergeButton.Enabled = false;
                selectedChangesButton.Enabled = false;
                loadCompleted = true;

            }
        }

        private void DestBranchListcomboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (loadCompleted)
            {
                loadCompleted = false;
                merger.DetermineWorkSpaces(SourceBranchListcomboBox.Text, DestBranchListcomboBox.Text);
                dataGridView1.DataSource = null;
                BulkMergeButton.Enabled = false;
                selectedChangesButton.Enabled = false;
                loadCompleted = true;
            }
        }


        private void userListComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            merger.selectedUser = userListComboBox.Text;
            if (loadCompleted)
            {
                loadCompleted = false;
                getUserWorkItemList();
                dataGridView1.DataSource = null;
                BulkMergeButton.Enabled = false;
                selectedChangesButton.Enabled = false;
                loadCompleted = true;

            }
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            waitLabel.Invoke(new Action(() => waitLabel.Visible = false));
        }

        public void SaveProjectName()
        {
            try
            {
                System.Configuration.Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                configuration.AppSettings.Settings["DefaultProjectName"].Value = merger.selectedProjectName;
                configuration.AppSettings.Settings["TfsUrl"].Value = merger.tfsUrl;
                configuration.Save();
                ConfigurationManager.RefreshSection("appSettings");
            }
            catch (Exception)
            {
                

               
            }

            try
            {
                if (merger.myCustomServerList != null && merger.myCustomServerList.serverList!=null)
              merger.myCustomServerList.serverList[0].TfsUrl = merger.tfsUrl;
                else
                {
                    merger.myCustomServerList  = new TFSServerList();
                      merger.myCustomServerList.serverList = new List<TFSServer>();
                    merger.myCustomServerList.serverList.Add(new TFSServer());
                    merger.myCustomServerList.serverList[0].TfsUrl = merger.tfsUrl;


                }
CustomServers cst = new CustomServers(merger);
cst.SerializeObject();
            }
            catch (Exception)
            {
                
                
            }
       
        }

        private void serverListCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (loadCompleted)
            {
                loadCompleted = false;
                string tfsurl = serverListCombo.SelectedValue.ToString();
                merger.tfsUrl = tfsurl;
                SaveProjectName();
                InitializeForm();
                loadCompleted = true;
            }
        }


 
        public void GetServersFromXML()
        {
            try
            {
                // Create an instance of the XmlSerializer specifying type and namespace.
                XmlSerializer serializer = new
                XmlSerializer(typeof(TFSServerList));

                // A FileStream is needed to read the XML document.
                FileStream fs = new FileStream("Servers.xml", FileMode.Open);
                StreamReader rd = new StreamReader(fs);
                string data = rd.ReadToEnd();
                StringReader reader = new StringReader(data);
                // Use the Deserialize method to restore the object's state.

                merger.myCustomServerList = (TFSServerList)serializer.Deserialize(reader);
                fs.Close();
                rd.Close();
            }
            catch (Exception ex)
            {

            }
        }

        private void addCustomServerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CustomServers customerServers = new CustomServers(merger);
            customerServers.ShowDialog();
        }

        private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
        {
            if (selectedMerge)
            {
                List<string> mergelist = new List<string>();
                for(int i = 0;i<dataGridView1.RowCount;i++)
                {
                    if(dataGridView1.Rows[i].Selected)
                        mergelist.Add(i.ToString());
                }
                    StartBulkMerge(mergelist);
            }
            else
            {
                StartBulkMerge();
            }
        }

        private void backgroundWorker3_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

            BulkMergeButton.Invoke(new Action(() => BulkMergeButton.Text = "Merge All Changeset"));
            merger.bulkmergeStarted = false;
        }

        private void TFSApiComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (loadCompleted)
            {
                loadCompleted = false;
                SaveProjectName();
                InitializeForm();

                loadCompleted = true;
            }
        }

        private void workItemListComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (loadCompleted)
            {
                loadCompleted = false;
                dataGridView1.DataSource = null;
                BulkMergeButton.Enabled = false;
                selectedChangesButton.Enabled = false;
                loadCompleted = true;
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            InitializeForm();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (PendingChangesListBox.CheckedItems != null && PendingChangesListBox.CheckedItems.Count > 0)
            {
                List<string> files = new List<string>();
                for (int i = 0; i < PendingChangesListBox.CheckedItems.Count; i++)
                {
                    files.Add(PendingChangesListBox.CheckedItems[i].ToString());
                }

                bool merged = merger.OnlyCheckIn(workItemTextBox.Text, commentTextBox.Text, files.ToArray());
                if (merged)
                {
                    object[] checkeditems = new object[PendingChangesListBox.CheckedItems.Count];
                 PendingChangesListBox.CheckedItems.CopyTo(checkeditems, 0);

                 foreach (var item in checkeditems)
                    {
                        PendingChangesListBox.Items.Remove(item);
                    }

                }

            }

        }




        public void log(string text)
        {
            if (text.Contains("\r\n"))
                logTextBox.Invoke(new Action(() => logTextBox.Text += text));
            else
                logTextBox.Invoke(new Action(() => logTextBox.Text += text + "\r\n"));

            logTextBox.Invoke(new Action(() => logTextBox.SelectionStart = logTextBox.Text.Length));
            logTextBox.Invoke(new Action(() => logTextBox.ScrollToCaret()));
            //Set the current caret position at the end
             //Now scroll it automatically
        }
        public void AddToPendingChanges(string itemurl, string Comment, string workitemID)
        {
            commentTextBox.Text = Comment;
            workItemTextBox.Text = workitemID;

            if (!string.IsNullOrEmpty(itemurl))
                PendingChangesListBox.Invoke(new Action(() => PendingChangesListBox.Items.Add(itemurl)));
            PendingChangesListBox.SetItemChecked(PendingChangesListBox.Items.Count - 1, true);
        }
        public void AddToPendingChanges(string itemurl, bool clear, string Comment, string workitemID)
        {
            if (clear)
                PendingChangesListBox.Items.Clear();
            AddToPendingChanges(itemurl, Comment, workitemID);
            //logTextBox.Invoke(new Action(() => logTextBox.Text += text + "\r\n"));
        }

        public void AddToConflictBox(string itemurl)
        {

            if (!string.IsNullOrEmpty(itemurl))
                ConflictListBox.Invoke(new Action(() => ConflictListBox.Items.Add(itemurl)));
        }
        public void AddToConflictBox(string itemurl, bool clear)
        {
            if (clear)
                ConflictListBox.Items.Clear();
            AddToConflictBox(itemurl);

        }

        private void button4_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            merger.ShowResolveConflictsDlg();
        }

        private bool selectedMerge = false;
        private void button4_Click_1(object sender, EventArgs e)
        {
            selectedMerge = true;
            PendingChangesListBox.Items.Clear();
            ConflictListBox.Items.Clear();
            workItemTextBox.Text = string.Empty;
            commentTextBox.Text = string.Empty;

            if (merger.mergeTable == null || merger.mergeTable.Rows.Count == 0)
            {
                MessageBox.Show("Lütfen öncelikle merge yapılacak branch'ları seçip, workItem'ın changesetlerini listeletiniz. Bunun için Branches listesinden Branch seçip, Workitems listesinden workitem seçip veya istediğiniz bir workitem'ın numarasını elle yazarak Listele butonuna basmanız yeterlidir.");
                return;
            }
            RefreshForm fr = new RefreshForm(FormRefresh);
            if (merger.bulkmergeStarted)
            {
                merger.bulkmergeStarted = false;
                fr.Invoke();
                return;
            }

            try
            {
                BulkMergeButton.Text = "Stop Process";
                merger.bulkmergeStarted = true;
                backgroundWorker3.RunWorkerAsync();


            }
            catch (Exception ex)
            {
                merger.bulkmergeStarted = false;
                MessageBox.Show(ex.Message);
                fr.Invoke();
                throw ex;
            }
        }

        private void dataGridView1_MultiSelectChanged(object sender, EventArgs e)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                selectedChangesButton.Enabled = true;
            }else
                selectedChangesButton.Enabled = false;
        }

        private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (dataGridView1.SelectedRows.Count > 0)
            {
                selectedChangesButton.Enabled = true;
            }
            else
                selectedChangesButton.Enabled = false;
        }


    }








}
